package com.CMUBiS.PageControllers;

import java.util.Date;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;

import javax.servlet.http.HttpServletRequest;

import com.CMUBiS.Data.Error;
import com.CMUBiS.Data.GlobalErrors;
import com.CMUBiS.Data.GlobalVars;
import com.CMUBiS.util.Category;
import com.CMUBiS.util.CheckInputs;
import com.CMUBiS.util.StopWatch;

/**
 * This is a blank example of a page controller. You can copy and edit it to make new pages
 * 
 * @author Andy (andrewtu@cmu.edu, turner.andy@gmail.com)
 * @version 0.1
 * @since 0.1
 * @date 04/05/2011
 */

public class SellItemController extends PageController{
	// Variables passed in the request
	private int userID = -1;
	private String authToken = null;
	private String name = null;
	private String description = null;
	private int quantity;
	private float startPrice;
	private float reservePrice;
	private float buyNowPrice;
	private Date endDate;
	private int categoryID = 0;
	
	// Structures to hold the DB data
	private ArrayList<Category> categories = null;
	
	// Structures to hold the parsed page data
	private String[] categorySelections;
	private String redirectURL = null;
	
	/**
	 * This method checks the page for any input errors that may have come from Client generator error
	 * These would need to be check in real life to stop users attempting to hack and mess with things
	 * 
	 * @param request
	 * @author Andy (andrewtu@cmu.edu, turner.andy@gmail.com)
	 */
	public void checkInputs(HttpServletRequest request){
		StopWatch timer;
		if(GlobalVars.collectStats){
			timer = new StopWatch();
			timer.start();
		}
		
		if(request != null){
			super.checkInputs(request);
			
			// Get the userID (if exists), we will pass it along to the next pages
			try{
				this.userID = CheckInputs.checkUserID(request);
			}
			catch(Error e){
				// The user must be logged in to sell
				if(!errors.contains(e))
					errors.add(e);
			}
			
			// Get the authToken (if exists), we will pass it along to the next pages
			try{
				this.authToken = CheckInputs.checkAuthToken(request);
			}
			catch(Error e){
				if(!errors.contains(e))
					errors.add(e);
			}
			
			// Get the item's name, there must be a name, so add an error if not valid
			this.name = CheckInputs.getParameter(request, "name");
			if(this.name.equals(EMPTY))
				if(!errors.contains(GlobalErrors.sellNoName))
					errors.add(GlobalErrors.sellNoName);
			
			// Get the item's description
			this.description = CheckInputs.getParameter(request, "description");
			
			// Get the quantity
			try{
				this.quantity = CheckInputs.checkQuantity(request);
			}
			catch(Error e){
				if(!errors.contains(e))
					errors.add(e);
				
				this.quantity = 1;
			}
			
			// Get the item's starting price
			try{
				this.startPrice = CheckInputs.checkStartPrice(request);
			}
			catch(Error e){
				if(!errors.contains(e))
					errors.add(e);
				
				this.startPrice = 0.0f;
			}
			
			// Get the item's reserve price
			try{
				this.reservePrice = CheckInputs.checkReservePrice(request);
			}
			catch(Error e){
				if(!errors.contains(e))
					errors.add(e);
				
				this.reservePrice = 0.0f;
			}
			
			// Get the item's buy now price
			try{
				this.buyNowPrice = CheckInputs.checkBuyNowPrice(request);
			}
			catch(Error e){
				if(!errors.contains(e))
					errors.add(e);
				
				this.buyNowPrice = 0.0f;
			}
			
			// Get the item's end date
			try{
				this.endDate = CheckInputs.checkEndDate(request);
			}
			catch(Error e){
				if(!errors.contains(e))
					errors.add(e);
				
				this.endDate = new Date(System.currentTimeMillis());
			}
			
			// Get the item's category
			try{
				this.categoryID = CheckInputs.checkCategoryID(request);
				
				if(this.categoryID<1)
					if(!errors.contains(GlobalErrors.sellCategoryIDInvalid))
						errors.add(GlobalErrors.sellCategoryIDInvalid);
			}
			catch(Error e){
				if(!errors.contains(e))
					errors.add(e);
				
				this.categoryID = 0;
			}
		}
		
		// Calculate how long that took
		if(GlobalVars.collectStats){
			timer.stop();
			this.totalGetParamTime += timer.getTimeTaken();
		}
	}

	/**
	 * This method get the data needed for the HTML4 page from the database
	 * 
	 * @author Andy (andrewtu@cmu.edu, turner.andy@gmail.com)
	 */
	public void getHTML4Data() {	
		StopWatch timer;
		if(GlobalVars.collectStats){
			timer = new StopWatch();
			timer.start();
		}
		
		// Get the categories the item can belong to
		try{
			categories = GlobalVars.db.getAllCategories();
		}
		catch(Exception e){
			errors.add(new Error("SellItemController: getHTML4Data: Could not get the categories", e));
		}
		
		// Calculate how long that took
		if(GlobalVars.collectStats){
			timer.stop();
			this.totalDBtime += timer.getTimeTaken();
		}
	}

	/**
	 * This method processes all of the data that was read from the database such that it is ready to be printed
	 * on to the page. We try to do as much of the page logic here as possible
	 * 
	 * @author Andy (andrewtu@cmu.edu, turner.andy@gmail.com)
	 */
	public void processHTML4() {
		StopWatch timer;
		if(GlobalVars.collectStats){
			timer = new StopWatch();
			timer.start();
		}
		
		// Make the category list items
		if(this.categories != null){
			categorySelections = new String[this.categories.size()];
			int length = this.categories.size();
			
			for(int i=0; i<length; i++)
				categorySelections[i] = "<option value=\"" + this.categories.get(i).getCategoryID() +"\""+ (this.categoryID==this.categories.get(i).getCategoryID()?" SELECTED":"") + ">" + this.categories.get(i).getName() + "</option>";
		}
		
		// Calculate how long that took
		if(GlobalVars.collectStats){
			timer.stop();
			this.totalProcessingTime += timer.getTimeTaken();
		}
	}
	
	/**
	 * Gets the HTML5 data from the database
	 * 
	 * @author Andy (andrewtu@cmu.edu, turner.andy@gmail.com)
	 */
	public void getHTML5Data(){
		StopWatch timer;
		if(GlobalVars.collectStats){
			timer = new StopWatch();
			timer.start();
		}
		
		// Calculate how long that took
		if(GlobalVars.collectStats){
			timer.stop();
			this.totalDBtime += timer.getTimeTaken();
		}
	}
	
	/**
	 * Processes the HTML5 data that is needed to create the page
	 * 
	 * @author Andy (andrewtu@cmu.edu, turner.andy@gmail.com)
	 */
	public void processHTML5(){
		StopWatch timer;
		if(GlobalVars.collectStats){
			timer = new StopWatch();
			timer.start();
		}
		
		// Calculate how long that took
		if(GlobalVars.collectStats){
			timer.stop();
			this.totalProcessingTime += timer.getTimeTaken();
		}
	}
	
	public boolean insertItem(){
		// Only attmept to insert if there are no errors
		if(this.errors.size() == 0)
			if(GlobalVars.db.checkAuthToken(this.userID, this.authToken)){
				// Make sure the reserve price is greater the the start price
				if((this.reservePrice > 0.0f) && (this.reservePrice < this.startPrice))
					if(!errors.contains(GlobalErrors.sellStartPriceGreaterThanReserve))
						errors.add(GlobalErrors.sellStartPriceGreaterThanReserve);
					
				// Make sure the buy now price is higher than the start and reserve price
				if((this.buyNowPrice > 0.0f) && (this.reservePrice > this.buyNowPrice))
						if(!errors.contains(GlobalErrors.sellReservePriceGreaterThanBuyNow))
							errors.add(GlobalErrors.sellReservePriceGreaterThanBuyNow);
				
				// Make sure the end date is later than now
				if(this.endDate != null && this.endDate.before(Calendar.getInstance().getTime()))
					if(!errors.contains(GlobalErrors.sellEndDateInPast))
						errors.add(GlobalErrors.sellEndDateInPast);
			
				// As everything is good we can insert the item
				if(this.errors.size()==0){
					boolean retVal = GlobalVars.db.insertItem(userID, name, description, startPrice, reservePrice, buyNowPrice, quantity, new java.sql.Time(this.endDate.getTime()), categoryID);
					this.createRedirectURL();
					return retVal;
				}
				return true;
			}
			else if(!errors.contains(GlobalErrors.incorrectAuthToken))
				errors.add(GlobalErrors.incorrectAuthToken);
		
		return false;
	}
	
	/**
	 * If we successfully insert the item then we can go to the conformation page.
	 * We'll create the URL here
	 * 
	 * @author Andy (andrewtu@cmu.edu, turner.andy@gmail.com)
	 */
	private void createRedirectURL(){
		this.redirectURL = "./confirmsellitem?userID="+this.getUserIDString()+"&authToken="+this.getAuthTokenString()+"&itemName="+this.getName();
	}
	
	/**
	 * Returns the current userID as a String
	 * 
	 * @return String the userID
	 * @author Andy (andrewtu@cmu.edu, turner.andy@gmail.com)
	 */
	public String getUserIDString(){
		return Integer.toString(this.userID);
	}
	
	/**
	 * Returns the authToken sent to the page
	 * 
	 * @return string the authToken
	 * @author Andy (andrewtu@cmu.edu, turner.andy@gmail.com)
	 */
	public String getAuthTokenString(){
		return this.authToken;
	}
	
	/**
	 * Returns the item's name sent to the page
	 * 
	 * @return string the name
	 * @author Andy (andrewtu@cmu.edu, turner.andy@gmail.com)
	 */
	public String getName(){
		return this.name;
	}
	
	/**
	 * Returns the item's description sent to the page
	 * 
	 * @return string the description
	 * @author Andy (andrewtu@cmu.edu, turner.andy@gmail.com)
	 */
	public String getDescription(){
		return this.description;
	}
	
	/**
	 * Returns the item's start price sent to the page
	 * 
	 * @return float the start price
	 * @author Andy (andrewtu@cmu.edu, turner.andy@gmail.com)
	 */
	public float getStartPrice(){
		return this.startPrice;
	}
	
	/**
	 * Returns the item's reserve price sent to the page
	 * 
	 * @return float the reserve price
	 * @author Andy (andrewtu@cmu.edu, turner.andy@gmail.com)
	 */
	public float getReservePrice(){
		return this.reservePrice;
	}
	
	/**
	 * Returns the item's buy now sent to the page
	 * 
	 * @return float the buy now price
	 * @author Andy (andrewtu@cmu.edu, turner.andy@gmail.com)
	 */
	public float getBuyNowPrice(){
		return this.buyNowPrice;
	}
	
	/**
	 * Returns the item's quantity sent to the page
	 * 
	 * @return int the quantity
	 * @author Andy (andrewtu@cmu.edu, turner.andy@gmail.com)
	 */
	public int getQuantity(){
		return this.quantity;
	}
	
	/**
	 * Returns the item's category ID sent to the page
	 * 
	 * @return int the category ID
	 * @author Andy (andrewtu@cmu.edu, turner.andy@gmail.com)
	 */
	public int getCategoryID(){
		return this.categoryID;
	}
	
	public String[] getCategorySelections(){
		return this.categorySelections;
	}
	
	/**
	 * Returns the item's end date sent to the page
	 * 
	 * @return Date the end date
	 * @author Andy (andrewtu@cmu.edu, turner.andy@gmail.com)
	 */
	public Date getEndDate(){
		return this.endDate;
	}
	
	/**
	 * Returns the URL to be redirected to if the user successfully registers
	 * 
	 * @return String the next URL to redirect to
	 * @author Andy (andrewtu@cmu.edu, turner.andy@gmail.com)
	 */
	public String getRedirectURL(){
		return this.redirectURL;
	}
}
